 
package Playlist_Management;

/**
 *
 * @author GeorgeD
 */


import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import Radiostation_POJOS.Playlist;
import Radiostation_POJOS.PlaylistSongs;
import Radiostation_POJOS.Song;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class PlayListXML {
    private final DateFormat df;    
    private boolean usedForExport;
    private EntityManager entityManager;
    
    public PlayListXML(EntityManager entityManager){   
        this.entityManager = entityManager;
        df = new SimpleDateFormat("dd/MM/yyyy");
    }
    
    public String readXml(File xmlFile) {
        Document document;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse(xmlFile);            
            document.getDocumentElement().normalize();

            Element playlistElement = document.getDocumentElement();                        
            Playlist playlist = new Playlist();
            playlist.setCreationdate(new Date());
            playlist.setName(playlistElement.getAttribute("name"));
            entityManager.persist(playlist);
            
            NodeList nList = document.getElementsByTagName("song");
            List<PlaylistSongs> playlistSongs = new ArrayList<>();
            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);                
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;
                    try{
                        Song song = this.entityManager
                            .createNamedQuery("Song.findBySongId", Song.class)
                            .setParameter("songId", Integer.parseInt(eElement.getAttribute("id")))
                            .getSingleResult();
                        
                        PlaylistSongs playlistSong = new PlaylistSongs();
                        playlistSong.setPlaylist(playlist);
                        playlistSong.setSong(song);
                        entityManager.persist(playlistSong);
                        playlistSongs.add(playlistSong);
                    } catch (NoResultException e){
                        entityManager.getTransaction().rollback();
                        return "Βρέθηκε Τραγούδι με κωδικό (ID) " + eElement.getAttribute("id") + " το οποίο δεν είναι καταχωρημένο στην βάση δεδομένων";
                    }
                }
            }
            if( !playlistSongs.isEmpty() ){
                playlist.setPlaylistSongList(playlistSongs);
                entityManager.persist(playlist);
                entityManager.getTransaction().commit();
                entityManager.getTransaction().begin();
                return null;
            } else {
                entityManager.getTransaction().rollback();
                return "Δεν βρέθηκαν Τραγούδια";
            }
        }catch (ParserConfigurationException | SAXException | IOException e){
            return "Πρόβλημα κατά την επεγεργασία του αρχείου";         
        }
    }
    
    public void writeXML(File xmlFile, Playlist playlist, List<Song> songs) {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder;
            docBuilder = docFactory.newDocumentBuilder();
            Document document = docBuilder.newDocument();
            Element rootElement = document.createElement("playlist");

            // set attribute name to playlist element
            Attr attrName = document.createAttribute("name");
            attrName.setValue(playlist.getName());
            rootElement.setAttributeNode(attrName);
            
            // set attribute creation date to playlist element
            Attr attrDate = document.createAttribute("creation_date");
            attrDate.setValue(df.format(playlist.getCreationdate()));
            rootElement.setAttributeNode(attrDate);
            
            // set attribute creation date to playlist element
            Attr attrId = document.createAttribute("id");
            attrId.setValue(playlist.getPlaylistId().toString());
            rootElement.setAttributeNode(attrId);
            
            document.appendChild(rootElement);

            Element root = document.getDocumentElement();

            for (Song s : songs) {
                // song elements                
                Element song = document.createElement("song");
                root.appendChild(song);

                // set attribute to song element
                Attr attr = document.createAttribute("id");
                attr.setValue(s.getSongId().toString());
                song.setAttributeNode(attr);

                // title elements
                Element title = document.createElement("title");
                title.appendChild(document.createTextNode(s.getTitle()));
                song.appendChild(title);

                // duration element
                Element duration = document.createElement("duration");
                duration.appendChild(document.createTextNode(Float.toString(Float.parseFloat(s.getDuration()))));
                song.appendChild(duration);

                // tracknr elements
                Element tracknr = document.createElement("tracknr");
                tracknr.appendChild(document.createTextNode(Integer.toString(s.getTracknr())));
                song.appendChild(tracknr);
            }

            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(xmlFile);
            transformer.transform(source, result);
            System.out.println("File saved!");
        } catch (ParserConfigurationException | DOMException | TransformerFactoryConfigurationError | TransformerException ex) {
            Logger.getLogger(PlayListXML.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void setUsedForExport(boolean usedForExport) {
        this.usedForExport = usedForExport;
    }

    public boolean isUsedForExport() {
        return usedForExport;
    }
}
